#include "functions.h"

/**
 * Miscellaneous functions used for the p2p application.  Listing of functions:
 * 
 * checkPort: validates the port number entered on the command line
 * parseArguments: parsees command line arguments and adds them to lists
 * printInitialPeers: prints the list of initial peers given on the command line
 *
 */
  
/**
 * Checks the port number. If successful, returns the port number.
 * If not, returns error message and exits.
 *
 * @param enteredPort - user entered port number
 * @return port - port as an int
 */
int checkPort(char * enteredPort) {

  //Variable to satisfy strol function.  Function sets this
  //pointer to the char after the numerical value`
  char * end;	

  //Convert enteredPort (string) to long integer
  long int tempPortnumber = strtol(enteredPort, &end, 10 ); //Base 10
    
  //Get length of entered argument
  int enteredPortLength = strlen(enteredPort);

  //If argument not numeric, exit
  //strtol points pointer given to where it stopped conversion
  //if no conversion done, it leaves pointer at beginning of string
  if ( enteredPort == end || (enteredPort + enteredPortLength != end) ) {
    error("Port number must be a two-byte short integer");
  }
    
  //If port out of range, exit
  if ( tempPortnumber <= 1024 || tempPortnumber > 65535){
    error("Port number out of range. Port must be between 1024 and 65535");
  }
        
  //If successful assign port number
  else {
    return (int) tempPortnumber;
  }
} // End checkPort


/**
 * Parses arguments
 */
int parseArgument(struct list * listLocalFiles, struct list * listInitialPeers, char * argument) {
  //Allocate memory for node containing peer address
  struct node * tempNode = malloc(sizeof(struct node));
  struct peer * tempPeer;
  
  //Define once, since argument will either be stored into a filename or address/port
  char * tempString = malloc(20);
  
  //Check if argument is a peer address  
  //check if argument contains '/'
  char * slashPointer;
  char * slashSearch;
  
  slashSearch = strchr(argument, '/');
   
  //If it does, split into tokens and store in peer struct
  if (slashSearch) {
    
    //Checks to ensure only one '/' is used
    if(strchr(slashSearch+1, '/')){
      error ("Only one '/' allowed"); 
    }
    
    //If only one '/' exits, then add peer to list
    else {
      slashPointer = strtok(argument, "/");
      
      //Create new node and peer struct and attach to list at head
      tempNode->next = NULL;
      
      tempPeer = malloc(sizeof(struct peer));
      
      //Assign peer to node
      tempNode->payload = tempPeer;

      //Push node onto list of initial peers
      push(listInitialPeers, tempNode);
      
      //Store address into peer struct
      tempString = malloc(strlen(slashPointer));
      strcpy(tempString, slashPointer);
      tempPeer->address = tempString;
      
      //Advance to next token
      slashPointer = strtok(NULL, "/");  

      //Store Port into peer struct
      tempString = malloc(strlen(slashPointer));
      strcpy(tempString, slashPointer);
      tempPeer->port= checkPort(tempString);
    } // End else
  }
  
  //This is not a peer address; it may be a filename
  else {
  
    //Check for errors in filename (illegal characters)
    /***NOT IMPLEMENTED YET****/
    
    //Copy into temporary string and 
    //Push element onto filenames list
    strcpy(tempString, argument);
    tempNode->payload = tempString;
    push (listLocalFiles, tempNode);
  }  

} // End parse arguments

/**
 * Prints the list of initial peers by iterating through the linked list
 * of peers and printing the values associated with each peer.
 *
 * @param list - initial peer list
 */
 
void printInitialPeers (struct list peerList) {
  
  struct node * itNode = createIterator(peerList);
   
  while (hasNext(itNode)){
  
    next(&itNode);
    struct peer * peerNode = (struct peer *) (itNode->payload);

    printf("PEER ADDRESS: %s\nPEER PORT: %d\n\n", peerNode->address, peerNode->port); 
  } // End while
  
} // End printInitialPeers